import re

from django import http
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db import DatabaseError
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from user.models import User
from areas.models import Address
from goods.models import SKU

from utils import constants, response_code
from utils.response_code import RETCODE
from utils.views import LoginRequiredJsonMixin
from utils.shoppingcart import merge_cart_cookie_to_redis


# 注册
class RegisterView(View):
    def get(self, request):
        return render(request, "register.html")

    def post(self, request):
        # 1、获取数据
        username = request.POST.get("username")
        password = request.POST.get("password")
        password2 = request.POST.get("password2")
        mobile = request.POST.get("mobile")
        sms_code = request.POST.get("sms_code")

        # 2、校验数据
        # 2.1  校验传入的数据是否完全
        if not all([username, password, password2, mobile]):
            return HttpResponse("数据缺失")
        # 2.2 校验用户名是否符合规范
        if not re.match(r"^[0-9a-zA-Z]{5,20}", username):
            return HttpResponse("请输入5-20个字符的用户名")
        # 2.3 校验一下当前的密码格式是否正确
        if not re.match(r"^[0-9a-zA-Z]{8,20}", password):
            return HttpResponse("请输入8-20个字符的用户名")
        # 2.4 校验一下两次输入的密码是否一致
        if password != password2:
            return HttpResponse("两次输入的密码不一致")
        # 2.4 校验手机号码是否正确
        if not re.match(r"^1[3-9]\d{9}$", mobile):
            return HttpResponse("手机号格式有误")

        redis_con = get_redis_connection("verifications")
        mobile_img = redis_con.get("phone_%s" % mobile).decode()
        print(mobile_img)
        if mobile_img is None:
            return http.JsonResponse({"code": RETCODE.SMSCODERR, "errmsg": "无效验证码"})

        if sms_code != mobile_img:
            return http.JsonResponse({"code": RETCODE.SMSCODERR, "errmsg": "验证码输入错误"})

        # 向数据库写入数据
        try:
            User.objects.create_user(username=username, password=password, mobile=mobile)
        except Exception as e:
            print(e)
            return http.JsonResponse({"code": RETCODE.DBERR, "errmsg": "注册失败"})

        return redirect(reverse("user:login"))


class UsernameView(View):
    def get(self, request, usernames):
        print("进入了函数")

        username_count = User.objects.filter(username=usernames).count()
        print("用户名数量：", username_count)

        return http.JsonResponse({"code": RETCODE.OK, "errmsg": RETCODE.OK, "count": username_count})


class MobileView(View):
    def get(self, request, mobile):
        print("进入手机数量函数")
        count = User.objects.filter(mobile=mobile).count()
        print("手机数量：", count)
        return http.JsonResponse({"code": RETCODE.OK, "errmsg": RETCODE.OK, "count": count})


# 登录
class LoginView(View):
    def get(self, request):
        return render(request, "login.html")

    def post(self, request):
        # 1、获取参数
        username = request.POST.get("username")
        password = request.POST.get("password")
        remembered = request.POST.get("remembered")
        print(remembered)
        # 2、校验参数
        # 2.1 参数是否齐全
        if not all([username, password]):
            return http.HttpResponseBadRequest("缺少参数")
        # 2.2 校验一下用户名是否符合规范
        if not re.match(r"^[0-9a-zA-Z]{5,20}", username):
            return render(request, "login.html", {"account_errmsg": "请输入正确的用户名以及密码"})
        # 2.3 校验一下当前的密码格式是否正确
        if not re.match(r"^[0-9a-zA-Z]{8,20}", password):
            return render(request, "login.html", {"account_errmsg": "密码最少8位，最长20位"})

        # 查询数据库
        user = authenticate(username=username, password=password)
        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})

        login(request, user)
        if remembered != "on":
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)

        # 获取next参数
        next = request.GET.get("next")
        if next:
            response = redirect(next)
        else:
            response = redirect(reverse('index:index'))
        response.set_cookie("username", user.username, max_age=60 * 60 * 24)

        response = merge_cart_cookie_to_redis(request=request, user=user, response=response)

        return response


# 退出登录
class LogoutView(View):
    def get(self, request):
        # 清楚设置的sessionid
        logout(request)

        # 清除存储的username
        response = redirect(reverse("user:login"))
        response.delete_cookie("username")

        return response


class UserCenterView(LoginRequiredMixin, View):
    def get(self, request):
        conten = {
            "username": request.user.username,
            "mobile": request.user.mobile,
            "email": request.user.email,
            "email_active": request.user.email_active,
        }

        return render(request, "user_center.html", conten)


class AddressView(LoginRequiredJsonMixin, View):
    def get(self, request):
        # 1、查询所有的收货地址
        # user_add = request.user.addresses
        try:
            user_add = Address.objects.filter(user=request.user, is_deleted=False)
        except Exception as e:
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '数据查询失败'})
        print("查询到的地址---->>>", user_add)
        address_list = []
        # 2、打包成json返回
        for i in user_add:
            address_list.append({
                "id": i.id,
                "title": i.title,
                "receiver": i.receiver,
                "province": i.province.name,
                "province_id": i.province_id,
                "city": i.city.name,
                "city_id": i.city_id,
                "district": i.district.name,
                "district_id": i.district_id,
                "place": i.place,
                "mobile": i.mobile,
                "tel": i.tel,
                "email": i.email
            })
        print(address_list)
        context = {
            "default_address_id": request.user.default_address_id,
            "addresses": address_list
        }

        return render(request, "user_center_site.html", context)


class PasswordView(LoginRequiredJsonMixin, View):
    def get(self, request):
        return render(request, "user_center_pass.html")

    def post(self, request):
        # 1、获取数据
        old_password = request.POST.get("old_password")
        new_password = request.POST.get("new_password")
        new_password2 = request.POST.get("new_password2")

        # 2、校验数据
        # 2.1 校验传入的数据是否有缺失
        if not all([old_password, new_password, new_password2]):
            return http.HttpResponseForbidden('缺少必传参数')
        # 2.2 校验旧密码是否正确
        if not request.user.check_password(old_password):
            return http.HttpResponseForbidden('旧密码输入错误')
        # 2.3 校验新密码的格式是否正确
        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return http.HttpResponseForbidden('密码格式输入有误')
        # 2.4 校验两次输入的密码是否一致
        if new_password != new_password2:
            return http.HttpResponseForbidden('两次密码不一致')

        # 修改密码
        try:
            request.user.set_password(new_password2)
            request.user.save()
        except Exception as e:
            print(e)
            return render(request, 'user_center_pass.html', {'change_password_errmsg': '修改密码失败'})

        logout(request)
        response = redirect(reverse("user:login"))
        response.delete_cookie("username")
        return response


class HistoryView(LoginRequiredJsonMixin, View):
    def get(self, request):
        # 获取用户对象
        user_id = request.user.id

        # 连接redis
        try:
            redis_con = get_redis_connection("history")
            history_data = redis_con.lrange("history_%s" % user_id, 0, 4)
        except Exception as e:
            print(e)
            return render(request, "404.html")
        skus = []
        for history in history_data:
            sku = SKU.objects.get(id=history)
            skus.append({
                "id": sku.id,  # 商品id
                "name": sku.name,  # 商品名字
                "default_image_url": sku.default_image,  # 默认商品ID
                "price": sku.price  # 商品单价
            })

        context = {
            "code": RETCODE.OK,
            "errmsg": "OK",
            "skus": skus
        }
        return http.JsonResponse(context)
